#include "pairwise_distance_neighborhood.h"
#include <malloc.h>
#include <stdio.h>

#include "xyz.h"

#include <stdlib.h>
#include <values.h>
#include <assert.h>
#include <math.h>

int main(void) {

  struct xyz_short center  = {0,0,0};

  short count;

  for(count = 2; count < 401; count++) {
    short i;
    struct xyz_short * objects = calloc(count, sizeof(struct xyz_short));
    short * paird  = malloc(sizeof(short) * pairwise_distance_neighborhood_get_array_size(count));
    short * paird2 = malloc(sizeof(short) * pairwise_distance_neighborhood_get_array_size(count));
    short * paird3 = malloc(sizeof(short) * pairwise_distance_neighborhood_get_array_size(count));

    short * sorted = malloc(sizeof(short) * (count+1));

    double d1, d2, d3;

    assert(paird);
    assert(paird2);
    assert(paird3);

    if(!(count % 10)) {
      printf("%d ", count);
      fflush(stdout);
    }

    for(i = 0; i < count; i++) {
      objects[i].x = (short)(100.0 * (float)((float)rand()/(float)RAND_MAX));
      objects[i].y = (short)(100.0 * (float)((float)rand()/(float)RAND_MAX));
      objects[i].z = (short)(100.0 * (float)((float)rand()/(float)RAND_MAX));
    }

    pairwise_distance_neighborhood_calculate(paird, sorted, &center, (char*)objects, count, sizeof(struct xyz_short), (double (*)(const void*,const void*))&xyz_short_distance);

    for(i = 0; i < count; i++) {
      objects[i].x = (short)(100.0 * (float)((float)rand()/(float)RAND_MAX));
      objects[i].y = (short)(100.0 * (float)((float)rand()/(float)RAND_MAX));
      objects[i].z = (short)(100.0 * (float)((float)rand()/(float)RAND_MAX));
    }

    pairwise_distance_neighborhood_calculate(paird2, sorted, &center, (char*)objects, count, sizeof(struct xyz_short),  (double (*)(const void*,const void*))&xyz_short_distance);

    for(i = 0; i < count; i++) {
      objects[i].x = (short)(100.0 * (float)((float)rand()/(float)RAND_MAX));
      objects[i].y = (short)(100.0 * (float)((float)rand()/(float)RAND_MAX));
      objects[i].z = (short)(100.0 * (float)((float)rand()/(float)RAND_MAX));
    }

    pairwise_distance_neighborhood_calculate(paird3, sorted, &center, (char*)objects, count, sizeof(struct xyz_short), (double (*)(const void*,const void*))&xyz_short_distance);

    d1 = pairwise_distance_neighborhood_distances(paird, paird2, count);
    d2 = pairwise_distance_neighborhood_distances(paird2, paird, count);


    assert(d1 >= 0);
    assert(d2 >= 0);


    assert(fabs(d1-d2) < 1.0000000000001);

    d1 = pairwise_distance_neighborhood_distances(paird, paird2, count);
    d2 = pairwise_distance_neighborhood_distances(paird2, paird3, count);
    d3 = pairwise_distance_neighborhood_distances(paird, paird3, count);

    assert(d1 >= 0);
    assert(d2 >= 0);
    assert(d3 >= 0);

    assert(d1+d2 >= d3 * 1.0000000000001);


    free(paird);
    free(paird2);
    free(paird3);
    free(objects);
  }

  printf("\nSuccess!\n");


  return 0;

}
